#pragma once

#include "aEngineModule.h"
#include "MessageReceiver.h"
#include "MessageSender.h"
#include "ThreadHelper.h"
#include "PredefinedBackgroundAgentMessages.h"



namespace _FOGGE_
{



	template <class T>
	class BackgroundAgent
		: public aEngineModule, 
		public _MSG_::MessageReceiver<T> ,
		public _MSG_::MessageSender,
		public _THREAD_::ThreadHelper

	{
	public:
		BackgroundAgent(void);
		~BackgroundAgent(void);

		void Update(float elapsedtime)
		{
			if(m_bIsInitialized==false)
				Initialize();
		}
		bool Initialize();
		void Finalize();


		DWORD ThreadProc();

	protected:
		HRESULT OnBackgroundWorkSet(_FOGGE_::_MSG_::Message* ptrMsg,_FOGGE_::_MSG_::Message* ptrRetMsg);
		
		
	private:
		_FOGGE_::_THREAD_::ThreadBlocker m_Blocker;

	};


	template <class T>
	BackgroundAgent<T>::BackgroundAgent(void)
		:_FOGGE_::aEngineModule(_FOGGE_::eEMID_BackgroundAgent,"BackgroundAgent")
	{
		RegisterHandler(_FOGGE_::_PMESSAGE_::ePBAM_BackgroundWorkSet,&BackgroundAgent<T>::OnBackgroundWorkSet);
	}

	template <class T>
	BackgroundAgent<T>::~BackgroundAgent(void)
	{
	}



	template <class T>
	bool BackgroundAgent<T>::Initialize()
	{
		// Start thread
		Begin();
		m_bIsInitialized=true;
		return true;
	}

	template <class T>
	void BackgroundAgent<T>::Finalize()
	{
		End();
	}

	template <class T>
	DWORD BackgroundAgent<T>::ThreadProc()
	{

		while(IsRunning())
		{
			Sleep(1);
			ProcessPostedMessage(GetMyID());
		}

		return 0;
	}


	template <class T>
	HRESULT BackgroundAgent<T>::OnBackgroundWorkSet(_FOGGE_::_MSG_::Message* ptrMsg,_FOGGE_::_MSG_::Message* ptrRetMsg)
	{

		_PBAMSG::PBAM_BackgroundWorkSet *ptrBWS=static_cast<_PBAMSG::PBAM_BackgroundWorkSet *>(ptrMsg);


		while(ptrBWS->m_JobList.empty()==false)
		{
			_FOGGE_::_MSG_::Message* ptrMessage=ptrBWS->m_JobList.front();
			ptrBWS->m_JobList.pop_front();

			//send to self, direct call
			ptrMessage->m_MessageType=_FOGGE_::_MSG_::eMT_PassMSG;
			SendMessageProc(ptrMessage,NULL);
			
			ptrMessage->FreeToPool();
		}

		if(ptrBWS->m_bNotifyWhenComplete)
		{
			
			_PBAMSG::PBAM_JobComplete *ptrJC=FoDynamicCast(_PBAMSG::PBAM_JobComplete,GetNewMassage(_FOGGE_::_PMESSAGE_::ePBAM_JobComplete));

			ptrJC->m_CompletedMessageID=ptrBWS->m_WorkSetID;

			BroadcastMessage(ptrJC);
		}
		


		return S_OK;
	}
}